/*

 * jddctmgr.c

 *

 * Copyright (C) 1994-1995, Thomas G. Lane.

 * This file is part of the Independent JPEG Group's software.

 * For conditions of distribution and use, see the accompanying README file.

 *

 * This file contains the inverse-DCT management logic.

 * This code selects a particular IDCT implementation to be used,

 * and it performs related housekeeping chores.  No code in this file

 * is executed per IDCT step, only during output pass setup.

 *

 * Note that the IDCT routines are responsible for performing coefficient

 * dequantization as well as the IDCT proper.  This module sets up the

 * dequantization multiplier table needed by the IDCT routine.

 */



#define JPEG_INTERNALS

#include "jinclude.h"

#include "jpeglib.h"

#include "jdct.h"		/* Private declarations for DCT subsystem */





/*

 * The decompressor input side (jdinput.c) saves away the appropriate

 * quantization table for each component at the start of the first scan

 * involving that component.  (This is necessary in order to correctly

 * decode files that reuse Q-table slots.)

 * When we are ready to make an output pass, the saved Q-table is converted

 * to a multiplier table that will actually be used by the IDCT routine.

 * The multiplier table contents are IDCT-method-dependent.  To support

 * application changes in IDCT method between scans, we can remake the

 * multiplier tables if necessary.

 * In buffered-image mode, the first output pass may occur before any data

 * has been seen for some components, and thus before their Q-tables have

 * been saved away.  To handle this case, multiplier tables are preset

 * to zeroes; the result of the IDCT will be a neutral gray level.

 */





/* Private subobject for this module */



typedef struct {

  struct jpeg_inverse_dct pub;	/* public fields */



  /* This array contains the IDCT method code that each multiplier table

   * is currently set up for, or -1 if it's not yet set up.

   * The actual multiplier tables are pointed to by dct_table in the

   * per-component comp_info structures.

   */

  int cur_method[MAX_COMPONENTS];

} my_idct_controller;



typedef my_idct_controller * my_idct_ptr;





/* Allocated multiplier tables: big enough for any supported variant */



typedef union {

  ISLOW_MULT_TYPE islow_array[DCTSIZE2];

#ifdef DCT_IFAST_SUPPORTED

  IFAST_MULT_TYPE ifast_array[DCTSIZE2];

#endif

#ifdef DCT_FLOAT_SUPPORTED

  FLOAT_MULT_TYPE float_array[DCTSIZE2];

#endif

} multiplier_table;





/* The current scaled-IDCT routines require ISLOW-style multiplier tables,

 * so be sure to compile that code if either ISLOW or SCALING is requested.

 */

#ifdef DCT_ISLOW_SUPPORTED

#define PROVIDE_ISLOW_TABLES

#else

#ifdef IDCT_SCALING_SUPPORTED

#define PROVIDE_ISLOW_TABLES

#endif

#endif





/*

 * Prepare for an output pass.

 * Here we select the proper IDCT routine for each component and build

 * a matching multiplier table.

 */



METHODDEF void

start_pass (j_decompress_ptr cinfo)

{

  my_idct_ptr idct = (my_idct_ptr) cinfo->idct;

  int ci, i;

  jpeg_component_info *compptr;

  int method = 0;

  inverse_DCT_method_ptr method_ptr = NULL;

  JQUANT_TBL * qtbl;



  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;

       ci++, compptr++) {

    /* Select the proper IDCT routine for this component's scaling */

    switch (compptr->DCT_scaled_size) {

#ifdef IDCT_SCALING_SUPPORTED

    case 1:

      method_ptr = jpeg_idct_1x1;

      method = JDCT_ISLOW;	/* jidctred uses islow-style table */

      break;

    case 2:

      method_ptr = jpeg_idct_2x2;

      method = JDCT_ISLOW;	/* jidctred uses islow-style table */

      break;

    case 4:

      method_ptr = jpeg_idct_4x4;

      method = JDCT_ISLOW;	/* jidctred uses islow-style table */

      break;

#endif

    case DCTSIZE:

      switch (cinfo->dct_method) {

#ifdef DCT_ISLOW_SUPPORTED

      case JDCT_ISLOW:

	method_ptr = jpeg_idct_islow;

	method = JDCT_ISLOW;

	break;

#endif

#ifdef DCT_IFAST_SUPPORTED

      case JDCT_IFAST:

	method_ptr = jpeg_idct_ifast;

	method = JDCT_IFAST;

	break;

#endif

#ifdef DCT_FLOAT_SUPPORTED

      case JDCT_FLOAT:

	method_ptr = jpeg_idct_float;

	method = JDCT_FLOAT;

	break;

#endif

      default:

	ERREXIT(cinfo, JERR_NOT_COMPILED);

	break;

      }

      break;

    default:

      ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);

      break;

    }

    idct->pub.inverse_DCT[ci] = method_ptr;

    /* Create multiplier table from quant table.

     * However, we can skip this if the component is uninteresting

     * or if we already built the table.  Also, if no quant table

     * has yet been saved for the component, we leave the

     * multiplier table all-zero; we'll be reading zeroes from the

     * coefficient controller's buffer anyway.

     */

    if (! compptr->component_needed || idct->cur_method[ci] == method)

      continue;

    qtbl = compptr->quant_table;

    if (qtbl == NULL)		/* happens if no data yet for component */

      continue;

    idct->cur_method[ci] = method;

    switch (method) {

#ifdef PROVIDE_ISLOW_TABLES

    case JDCT_ISLOW:

      {

	/* For LL&M IDCT method, multipliers are equal to raw quantization

	 * coefficients, but are stored in natural order as ints.

	 */

	ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;

	for (i = 0; i < DCTSIZE2; i++) {

	  ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[jpeg_zigzag_order[i]];

	}

      }

      break;

#endif

#ifdef DCT_IFAST_SUPPORTED

    case JDCT_IFAST:

      {

	/* For AA&N IDCT method, multipliers are equal to quantization

	 * coefficients scaled by scalefactor[row]*scalefactor[col], where

	 *   scalefactor[0] = 1

	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7

	 * For integer operation, the multiplier table is to be scaled by

	 * IFAST_SCALE_BITS.  The multipliers are stored in natural order.

	 */

	IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;

#define CONST_BITS 14

	static const INT16 aanscales[DCTSIZE2] = {

	  /* precomputed values scaled up by 14 bits */

	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,

	  22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,

	  21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,

	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,

	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,

	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,

	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,

	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247

	};

	SHIFT_TEMPS



	for (i = 0; i < DCTSIZE2; i++) {

	  ifmtbl[i] = (IFAST_MULT_TYPE)

	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]],

				  (INT32) aanscales[i]),

		    CONST_BITS-IFAST_SCALE_BITS);

	}

      }

      break;

#endif

#ifdef DCT_FLOAT_SUPPORTED

    case JDCT_FLOAT:

      {

	/* For float AA&N IDCT method, multipliers are equal to quantization

	 * coefficients scaled by scalefactor[row]*scalefactor[col], where

	 *   scalefactor[0] = 1

	 *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7

	 * The multipliers are stored in natural order.

	 */

	FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;

	int row, col;

	static const double aanscalefactor[DCTSIZE] = {

	  1.0, 1.387039845, 1.306562965, 1.175875602,

	  1.0, 0.785694958, 0.541196100, 0.275899379

	};



	i = 0;

	for (row = 0; row < DCTSIZE; row++) {

	  for (col = 0; col < DCTSIZE; col++) {

	    fmtbl[i] = (FLOAT_MULT_TYPE)

	      ((double) qtbl->quantval[jpeg_zigzag_order[i]] *

	       aanscalefactor[row] * aanscalefactor[col]);

	    i++;

	  }

	}

      }

      break;

#endif

    default:

      ERREXIT(cinfo, JERR_NOT_COMPILED);

      break;

    }

  }

}





/*

 * Initialize IDCT manager.

 */



GLOBAL void

jinit_inverse_dct (j_decompress_ptr cinfo)

{

  my_idct_ptr idct;

  int ci;

  jpeg_component_info *compptr;



  idct = (my_idct_ptr)

    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,

				SIZEOF(my_idct_controller));

  cinfo->idct = (struct jpeg_inverse_dct *) idct;

  idct->pub.start_pass = start_pass;



  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;

       ci++, compptr++) {

    /* Allocate and pre-zero a multiplier table for each component */

    compptr->dct_table =

      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,

				  SIZEOF(multiplier_table));

    MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));

    /* Mark multiplier table not yet set up for any method */

    idct->cur_method[ci] = -1;

  }

}

